<template>
  <div class="mapContainer" :name="containerStyle">
    <!--Leaflet地图容器-->
    <div id="leafletContainer" :name="mapStyle" @click="mapClick"></div>
    <!-- 点选查询 -->
    <pointQuery :style="pointQueryWindowStyle" />
    <!-- 查询结果信息框 -->
    <router-view name="queryInfo"></router-view>
    <!-- 工具栏 -->
    <router-view name="toolBar"></router-view>
    <!-- 详细信息展示框 -->
    <router-view name="detailInfo"></router-view>
    <!-- 多边形选查询 -->
    <polygon-query />
  </div>
</template>

<script>
/* eslint-disable */
import { getCurrentInstance, onMounted, ref } from "vue";
import { useRouter } from "vue-router";
import "leaflet/dist/leaflet.css";
import L from "leaflet";
import "@supermap/iclient-leaflet";
import pubsub from "pubsub-js";
import icon from "leaflet/dist/images/marker-icon1.png";
import iconShadow from "leaflet/dist/images/marker-shadow.png";

import mapApi from "@/api/mapApi.js";
import normalApi from "@/api/normalApi.js";

import Message from "@/components/Message/showMessage";
import pointQuery from "@/components/PointQuery/pointQuery.vue";
import queryInfo from "@/components/QueryInfo/queryInfo.vue";
import polygonQuery from "@/components/PolygonQuery/polygonQuery.vue";
import detailInfo from "@/components/DetailInfo/detailInfo.vue";

export default {
  name: "Leaflet地图",
  components: {
    pointQuery,
    queryInfo,
    polygonQuery,
    detailInfo,
  },
  data() {
    return {
      // pubsub列表
      subList: [],
      // 容器样式
      containerStyle: "layerManagerShow",
      // 地图容器样式
      mapStyle: "mapStyle",
      // 点选距离弹窗样式
      pointQueryWindowStyle: { top: 0, left: 0 },
      // 地图点选点击点
      clickPoint: {},
      // 点选距离弹窗top/left距离
      pointWindow: { offsetX: 0, offsetY: 0 },
      // 信息列表显隐
      queryInfoShow: false,
      // 信息列表数据
      queryInfoDataProp: {},
      // 详细信息显隐
      detailInfoShow: false,
      // 详细信息数据
      detailInfoDataProp: [],
    };
  },
  setup() {
    // 在setup中使用data的数据
    const { proxy } = getCurrentInstance();
    const router = useRouter();
    const containerRef = ref(null);

    // 各类标识列表
    window._markerList = {
      // 单一名称标注
      namePopup: undefined,
      // 高亮面要素
      highlightPolygonList: [],
      // 高亮marker
      highlightMark: undefined,
      // 高亮点选查询面
      highlightCircle: undefined,
      // 单个查询结果popup
      pointQueryResultPopup: [],
      // 单个查询结果绘制结果
      pointQueryResultDraw: [],
      // 长方形临时查询点
      tempRectangularPointList: [],
      // 长方形临时查询面
      tempRectangularPolygon: undefined,
      // 长方形查询点
      rectangularPointList: [],
      // 长方形查询面
      rectangularPolygon: undefined,
      // 多边形临时查询点
      tempPolygonPointList: [],
      // 多边形临时查询面
      tempPolygonLayer: undefined,
      // 多边形查询点
      polygonPointList: [],
      // 多边形查询面
      polygonLayer: undefined,
      // 套索面查询面
      lassoLayer: undefined,
      // 套索面另存
      lassoPolygon: undefined,
    };

    // icon样式载入
    const DefaultIcon = L.icon({
      iconUrl: icon,
      shadowUrl: iconShadow,
      iconAnchor: [13.5, 40],
    });
    L.Marker.prototype.options.icon = DefaultIcon;

    // 实例被挂载后调用
    onMounted(() => {
      // normalApi.getUrlJson();
      mapApi.initMap();
      subscribeList();
    });

    //订阅列表
    function subscribeList() {
      proxy.subList.push(
        // 地图显示控制
        pubsub.subscribe("basicalMapChange", (n, data) => {
          // 打开地图
          if (data.isChecked) {
            mapApi.addMap(data.nodeData);
          }
          // 关闭地图
          else {
            mapApi.layerList.forEach((element) => {
              if (element.label === data.nodeData.label) {
                _map.removeLayer(element.layer);
                mapApi.layerList.splice(mapApi.layerList.indexOf(element), 1);
              }
            });
          }
        }),
        // 图层透明度变化
        pubsub.subscribe("opacityChange", (n, data) => {
          mapApi.layerList.forEach((element) => {
            if (element.label === data.label) {
              element.layer.setOpacity(1 - data.opacity / 100);
            }
          });
        }),
        // 点要素标注绘制
        pubsub.subscribe("toPointAddress", (n, point) => {
          // 企业详细信息显示
          if (point.data) {
            // console.log(point.data);
            let result = mapApi.enterpriseDataHandle(point.data);
            // 路由跳转
            router.push({
              name: "detailInfo",
              params: { detailInfoDataProp: JSON.stringify(result) },
            });
          }
          // 隐藏搜索框
          pubsub.publish("dropDownShowControll", false);
          // 消除旧标识
          mapApi.deleteMarker([]);
          // 读取中心坐标
          let centerPoint =
            point.address === undefined
              ? [point.center.lat, point.center.lng]
              : [point.address.y, point.address.x];

          setTimeout(() => {
            _map.invalidateSize();
            // 绘制标注
            _markerList.namePopup = L.popup()
              .setLatLng(centerPoint)
              .setContent(
                `<div style='color:#3f69e4;text-align:'center'>` +
                  point.name +
                  `</div>`
              )
              .addTo(_map);
            //视图变换
            _map.setView(centerPoint, 7);
          }, 300);
        }),
        // 面要素标注绘制
        pubsub.subscribe("toPolygonAddress", (n, address) => {
          proxy.queryInfoShow = false;
          // console.log(address);
          // 隐藏搜索框
          pubsub.publish("dropDownShowControll", false);
          // 消除旧标识
          mapApi.deleteMarker([]);
          // 转置
          let lineList = mapApi.coordinateReverse(address.rings);
          // 绘制高亮
          let highLightArr = [];
          highLightArr.push(
            L.polygon(lineList, {
              color: "red",
              fillColor: "red",
              fillOpacity: 0.3,
            }).addTo(_map)
          );
          _markerList.highlightPolygonList = highLightArr;
          // 绘制标注
          _markerList.namePopup = L.popup()
            .setLatLng([address.center.lat, address.center.lng])
            .setContent(`<div style='color:#3f69e4'>` + address.name + `</div>`)
            .addTo(_map);
          // 视角移动
          _map.setView(address.center, mapApi.lengthToLayer(address.length));
        }),
        // 线要素标注绘制
        pubsub.subscribe("toPolylineAddress", (n, address) => {
          proxy.queryInfoShow = false;
          // console.log(address);
          // 隐藏搜索框
          pubsub.publish("dropDownShowControll", false);
          // 消除旧标识
          mapApi.deleteMarker([]);
          // 转置
          let lineList = mapApi.coordinateReverse(address.paths);
          // 绘制高亮
          let highLightArr = [];
          lineList.forEach((line) => {
            highLightArr.push(L.polyline(line, { color: "red" }).addTo(_map));
          });
          _markerList.highlightPolygonList = highLightArr;
          // 绘制标注
          _markerList.namePopup = L.popup()
            .setLatLng([address.center.lat, address.center.lng])
            .setContent(`<div style='color:#3f69e4'>` + address.name + `</div>`)
            .addTo(_map);
          // 视角移动
          _map.setView(address.center, mapApi.lengthToLayer(address.length));
        }),
        // 清除标识
        pubsub.subscribe("deleteMarker", (n, data) => {
          mapApi.deleteMarker(data);
        }),
        // 点选查询
        pubsub.subscribe("pointQuery", (n, data) => {
          // 鼠标样式设置
          document.querySelector("#leafletContainer").style.cursor = data
            ? "crosshair"
            : "grab";
          // 信息提示
          Message(`点选查询已${data ? `开启` : `关闭`}`);
          mapApi.deleteMarker([]);
          if (data) {
            // 开启功能
            // 获取点击的屏幕top/left距离
            mapApi.getMapClickLocation(true, (rect) => {
              proxy.pointWindow.offsetX = rect.width / 2;
              proxy.pointWindow.offsetY = rect.height / 2;
            });
            // 获取点击事件的实际坐标
            _map.on("click", mapClickQueryRun);
          } else {
            // 关闭功能
            // 地图点击关闭
            _map.off("click", mapClickQueryRun);
            // 屏幕点击关闭
            mapApi.getMapClickLocation(false);
            // 清除旧信息
            _markerList["highlightMark"] != undefined
              ? mapApi.deleteMarker(["highlightMark"])
              : pubsub.publish("infoDrawClear");
            // 查询范围隐藏
            pubsub.publish("pointQueryWindowShow", {
              flag: false,
              clickPoint: {},
            });
            pubsub.publish("queryInfoShow", { flag: false });
          }
        }),
        // 绘制点选查询范围
        pubsub.subscribe("drawQueryCircle", (n, data) => {
          if (data.flag) {
            // 绘制
            // 清除旧高亮标识
            mapApi.deleteMarker(["highlightCircle"]);
            // 绘制新高亮标识
            _markerList.highlightCircle = L.circle(data.centerPoint, {
              color: "#3f69e4",
              fillColor: "#3f69e4",
              fillOpacity: 0.1,
              radius: data.radius,
            }).addTo(_map);
          } else {
            // 清除
            mapApi.deleteMarker(["highlightCircle"]);
          }
        }),
        // 点选查询结果绘制
        pubsub.subscribe("infoDetailShow", (n, data) => {
          // 删除旧标识、隐藏查询面
          mapApi.deleteMarker([
            "pointQueryResultPopup",
            "pointQueryResultDraw",
          ]);
          // 添加标识
          mapApi.pointQueryResultShow(data.info, data.type);
          console.log(data.info, data.type);
          // 企业信息展示
          if (data.info.attributes.qymc) {
            // 列表隐藏
            proxy.queryInfoShow = false;
            // 企业数据处理
            let result = mapApi.enterpriseDataHandle(data.info.attributes);
            console.log(result);
            // 路由跳转
            router.push({
              name: "detailInfo",
              params: { detailInfoDataProp: JSON.stringify(result) },
            });
          }
        }),
        // 查询结果列表显隐
        pubsub.subscribe("queryInfoShow", (n, data) => {
          // 地图样式改变
          proxy.mapStyle = data.flag ? "dataStyle" : "mapStyle";
          // 路由跳转
          if (data.flag) {
            router.push({
              name: "queryInfo",
              params: { queryInfoDataProp: JSON.stringify(data.resultList) },
            });
          } else {
            router.push({
              name: "map",
            });
          }
        }),
        // 清空点选查询结果
        pubsub.subscribe("infoDrawClear", (n, data) => {
          // 清除图上标注
          mapApi.deleteMarker([
            "namePopup",
            "highlightPolygonList",
            "highlightCircle",
          ]);
          // 清除信息列表
          proxy.queryInfoShow = false;
          Message("已清除查询结果，可重新查询");
        }),
        // 框选查询
        pubsub.subscribe("rectangularQuery", (n, data) => {
          // 鼠标样式设置
          document.querySelector("#leafletContainer").style.cursor = data
            ? "crosshair"
            : "grab";
          // 信息提示
          Message(`四边形查询已${data ? `开启` : `关闭`}`);
          // 删除各类地图标识
          mapApi.deleteMarker([]);
          // 功能开关
          if (data) {
            // 开启功能
            _map.on("click", mapRectangularClickRun);
            _map.on("mousemove", mapRectangularMoveRun);
          } else {
            // 关闭功能
            _map.off("click", mapRectangularClickRun);
            _map.off("mousemove", mapRectangularMoveRun);
            pubsub.publish("queryInfoShow", { flag: false });
          }
        }),
        // 多边形查询
        pubsub.subscribe("polygonQuery", (n, data) => {
          // 鼠标样式设置
          document.querySelector("#leafletContainer").style.cursor = data
            ? "crosshair"
            : "grab";
          // 信息提示
          Message(`多边形查询已${data ? `开启` : `关闭`}`);
          mapApi.deleteMarker([]);
          if (data) {
            // 开启功能
            _map.on("click", mapPolygonClickRun);
            _map.on("dblclick", mapPolygonDoubleClickRun);
          } else {
            // 关闭功能
            _map.off("click", mapPolygonClickRun);
            _map.off("dblclick", mapPolygonDoubleClickRun);
            pubsub.publish("queryInfoShow", { flag: false });
          }
        }),
        // 套索面查询
        pubsub.subscribe("mouseQuery", (n, data) => {
          // 鼠标样式设置
          document.querySelector("#leafletContainer").style.cursor = data
            ? "crosshair"
            : "grab";
          // 信息提示
          Message(`套索面查询已${data ? `开启` : `关闭`}`);
          // 标识清除
          mapApi.deleteMarker([]);
          if (data) {
            // 开启功能
            _map.on("click", mapLassoMouseClickRun);
            _map.on("mousemove", mapLassoMouseMoveRun);
          } else {
            // 关闭功能
            mapApi.lassoDrawingFlag = false;
            mapApi.deleteMarker(["lassoLayer"]);
            _map.off("click", mapLassoMouseClickRun);
            _map.off("mousemove", mapLassoMouseMoveRun);
            pubsub.publish("queryInfoShow", { flag: false });
          }
        }),
        // 查询结果数据总览
        pubsub.subscribe("seeAllData", (n, data) => {
          // 清除其他标注
          mapApi.deleteMarker([
            "pointQueryResultPopup",
            "pointQueryResultDraw",
          ]);
          // 显隐控制
          if (data.seeAllflag) {
            // 分类绘制
            mapApi.seeAllData(data);
          } else {
            // 关闭绘制
            mapApi.seeAllDataClose();
          }
        }),
        // 图层管理控件显隐
        pubsub.subscribe("layerManagerShowChange", (n, data) => {
          proxy.containerStyle = data ? "layerManagerShow" : "layerManagerHide";
        }),
        // 地图控件样式变化
        pubsub.subscribe("mapExpand", (n, data) => {
          proxy.mapStyle = data;
        })
      );
    }

    // 地图点选查询总起
    function mapClickQueryRun(e) {
      mapApi.mapClickQuery(e, (result) => {
        proxy.clickPoint = result;
      });
    }

    // 四边形查询总起-绘制查询点-鼠标单击
    function mapRectangularClickRun(e) {
      mapApi.mapRectangularClick(e, mapRectangularMoveRun);
    }

    // 四边形查询总起-绘制查询面-鼠标移动
    function mapRectangularMoveRun(e) {
      mapApi.mapRectangularMove(e);
    }

    // 多边形查询总起-绘制查询点-鼠标单击
    function mapPolygonClickRun(e) {
      mapApi.mapPolygonClick(e);
    }

    // 多边形查询总起-结束绘制查询点-鼠标双击
    function mapPolygonDoubleClickRun(e) {
      mapApi.mapPolygonClickConfrim(e);
    }

    // 套索面查询总起-开始绘制套索面-鼠标单击
    function mapLassoMouseClickRun(e) {
      mapApi.mapLassoMouseClick(e);
    }

    // 套索面查询总起-绘制套索面-鼠标移动
    function mapLassoMouseMoveRun(e) {
      mapApi.mapLassoMouseMove(e);
    }

    // 地图点击
    function mapClick() {
      // 关闭搜索结果框
      pubsub.publish("dropDownShowControll", false);
    }

    return { containerRef, mapClick };
  },
  watch: {
    // 地图点击后弹出距离设置弹窗
    clickPoint(newValue) {
      setTimeout(() => {
        // 设置距离
        this.pointQueryWindowStyle = {
          top: this.pointWindow.offsetY - 30 + "px",
          left: this.pointWindow.offsetX + 20 + "px",
        };
        // 弹窗弹出
        pubsub.publish("pointQueryWindowShow", {
          flag: true,
          clickPoint: newValue,
        });
      }, 30);
    },
    // leaflet地图容器宽度
    mapStyle: {
      handler(newValue) {
        console.log("mapStyle changed:" + newValue);
        setTimeout(() => {
          _map.invalidateSize();
        }, 300);
      },
      immediate: true,
    },
    containerStyle() {
      setTimeout(() => {
        _map.invalidateSize();
      }, 300);
    },
  },
  beforeDestroy() {
    this.subList.forEach((element) => {
      pubsub.unsubscribe(element);
    });
  },
  beforeRouteLeave() {
    this.subList.forEach((element) => {
      pubsub.unsubscribe(element);
    });
  },
};
</script>

<style lang="less" scoped>
.mapContainer {
  height: 94%;
  background-color: white;
  padding: 0.2%;
  margin-right: 0.25%;
  float: right;
  position: relative;
  top: 5.5%;
  border-radius: 5px;
  display: flex;
  flex-direction: row;
  transition: width 0.3s ease;
  > #leafletContainer {
    height: 100%;
    border-radius: 5px;
    background-color: rgb(238, 238, 238);
    transition: width 0.3s ease;
  }
  [name="mapStyle"] {
    width: 100%;
  }
  [name="dataStyle"] {
    width: 50%;
    box-shadow: 2px 2px 5px 1px rgba(0, 0, 0, 0.5);
  }
}
[name="layerManagerShow"] {
  width: 84.25%;
}
[name="layerManagerHide"] {
  width: 97.5%;
}

.pointQuery {
  position: absolute;
}
</style>